import re
from typing import List, Union
from apps.tests.models import CaseRunLog
from core.common import formatter_log, get_module_functions, single_replace_data
from core.step_model import CheckModel, RunModel


def _check_text(check_type, exp, act):
    return '【{}】 【预期值类型：{}】 【实际值值类型：{}】 【预期值：{}】  【实际值：{}】'.format(check_type, type(exp), type(act),
                                                                   exp, act)


def check_equal(exp_type, exp, act, params_class, case_logs_obj, is_check=True):
    act = single_replace_data(params_class, case_logs_obj, act)
    if exp_type == "Dynamic":
        exp = single_replace_data(params_class, case_logs_obj, exp)

    if exp == act:
        if is_check:
            case_logs_obj.logs.append(formatter_log('success', _check_text('断言相等', exp, act)))
        return True
    else:
        if is_check:
            case_logs_obj.logs.append(formatter_log('failed', _check_text('断言相等', exp, act)))
            case_logs_obj.result = CaseRunLog.CaseResult.FAIL
        return False


CHECK_FUNC_MAP = get_module_functions('core.check')


def loop_assert_by_check_list(check_list: Union[List[CheckModel], List[RunModel]],
                              params_class, case_logs_obj, is_check=True, result=True):

    for index, check_obj in enumerate(check_list):
        check_result = CHECK_FUNC_MAP[check_obj.method](check_obj.type, check_obj.exp, check_obj.act, params_class,
                                                        case_logs_obj, is_check=is_check)

        if not is_check:
            if index == 0:
                result = check_result
            else:
                result = result and check_result if check_list[index - 1].andOr == 'And'\
                    else result or check_result
    return result
